package com.wn.advice;

import com.wn.annonation.MyLimit;
import com.wn.annonation.MyRedisCache;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author yellow Docter
 * @date 2022 -10-28
 * @desc
 *  切面
 */
@Component
@Aspect
@Slf4j
public class MyRedisCacheAdvice {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;


    /**
     * 编写通知的增强的方法
     *
     *   @Around() 环绕通知：在目标方法的前后可以进行增强
     *
     *   ProceedingJoinPoint 程序的连接点（增强的方法）
     *
     *    @Around(value = "execution( 切点表达式 )")
     *
     *
     * @return
     */
    @Around(value = "execution(* com.wn.service.impl.MemberServiceImpl.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        //拿到方法 的签名
        MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
        //拿到方法的对象
        Method method = methodSignature.getMethod();

        if (method.isAnnotationPresent(MyRedisCache.class)){
            MyRedisCache annotation = method.getAnnotation(MyRedisCache.class);
            String redisKey = annotation.value();

            String data = stringRedisTemplate.opsForValue().get(redisKey);
            //第一次 查询数据库
            if (Objects.isNull(data)){
                //查询db
                Object proceed = pjp.proceed();
                log.info("第一次获取数据库查询数据.....");
                //存储到redis中
                stringRedisTemplate.opsForValue().set(redisKey,proceed.toString());
                return proceed;
            }else{
                log.info("第n次获取数据.....从redis中获取数据.....");
                //第二次从redis中获取
                return stringRedisTemplate.opsForValue().get(redisKey);
            }
        }
        return pjp.proceed();
    }

}
